import axios from 'axios'
import qs from 'qs'
import { handleError } from 'vue'
import { showProgress, hideProgress, msg, getType } from '../utils/utils'

let FieldKeys = {}
let instance = axios.create({
	baseURL: "",
	timeout: 1000 * 60 * 5,
	headers: {
		// "Content-Type": "application/x-www-form-urlencoded",
		// "Content-Type": "multipart/form-data",
		"Content-Type": "application/json",
		// Authorization: "Bearer " + token,
		// timeStamp: Date.parse(new Date()) / 1000,
		app: 0
	},
	// transformRequest: [(data) => {
	//   return data
	// }],
	// transformResponse: [(data) => {
	//   return JSON.parse(data)
	// }],
	paramsSerializer: {
		serialize: function(params) {
			return qs.stringify(params, { arrayFormat: 'repeat' })
		}
	},
	params: {},
	data: {},
	// 自定义处理请求
	// adapter: (config) => {
	// },
	responseType: "json",
	onUploadProgress: (progressEvent) => {

	},
	onDownloadProgress: (progressEvent) => {
		// console.log("下载进度", progressEvent)
	},
	validateStatus: (status) => {
		return status >= 200 && status < 300
	}
})

// request before -> set

instance.interceptors.request.use(async config => {
	// -------------------- 时间戳 --------------------
	config.params.timeStamp = Date.parse(new Date()) / 1000

	// -------------------- 获取token --------------------
	let token = localStorage.getItem("token")

	// -------------------- 数据处理 --------------------
	// ["form", "file", "exParam","exData", "arrParam", "noToken", "customError", "getArr", "integral", "arrayToObject"]
	// params 过滤
	for (let key in config.params) {
		let Str = String(config.params[key])
		if (Str == 'undefined' || Str == 'null' || Str == '') delete config.params[key]
	}

	for (let key in config.data) {
		let Str = String(config.data[key])
		if (Str == 'undefined' || Str == 'null' || Str == '') delete config.data[key]
	}

	// 列表
	if (config.data.data && config.exConfig && config.exConfig.includes("arrayToObject")) {
		for (let key in config.data.data) {
			let Str = String(config.data.data[key])
			if (Str == 'undefined' || Str == 'null' || Str == '') delete config.data.data[key]
		}
		FieldKeys = config.data.data.FieldKeys.split(",")
	}

	// GET 数组？、
	// POST、PUT...  文件(√)、form(√)、额外参数(√)
	if (config.exConfig) {
		if (config.exConfig.includes("form")) {
			config.headers["Content-Type"] = "application/x-www-form-urlencoded"
			config.data = qs.stringify(config.data)
		}
		if (config.exConfig.includes("file")) config.headers["Content-Type"] = "multipart/form-data"
		if (config.exConfig.includes("exParam")) config.params = config.exData
		if (config.exConfig.includes("exData")) config.data = config.exData
		if (config.exConfig.includes("getArr")) config.paramsSerializer = () => {
			return qs.stringify(config.params, {
				arrayFormat: 'repeat'
			})
		}
	}
	config.headers["Authorization"] = 'Bearer ' + token
	return config

}, (error) => {
	Promise.reject(error)
})

// 
let statusMsg = {
	400: "错误请求 ！",
	401: "用户凭证过期，请重新登录 ！",
	403: "拒绝访问 ！",
	404: "请求错误,未找到该资源 ！",
	405: "请求方法未允许 ！",
	408: "请求超时 ！",
	500: "请求服务器失败 ！",
	501: "网络未实现 ！",
	502: "网络错误 ！",
	503: "服务不可用 ！",
	504: "网络超时 ！",
	505: "http版本不支持该请求 ！"
}

let MsgCodeList = {
	1: "上下文丢失",
	2: "没有权限",
	3: "操作标识为空",
	4: "异常",
	5: "单据标识为空",
	6: "数据库操作失败",
	7: "许可错误",
	8: "参数错误",
	9: "指定字段 / 值不存在",
	10: "未找到对应数据",
	11: "验证失败",
	12: "不可操作",
	13: "网控冲突",
	14: "调用限制",
	15: "禁止管理员登录"
}

let loginMsg = {
	// -7: "激活",
	// -6: "云通行证未绑定Cloud账号",
	// -5: "需要表单处理",
	// -4: "登录警告",
	// -3: "密码验证不通过",
	// -2: "密码验证不通过",
	// -1: "登录失败",
	// 0: "用户或密码错误"
}

let handleMsgCode = (msgcode) => {
	if (msgcode === 1) {
		// 重新登录
		uni.redirectTo({
			url: '/views/login/Loading'
		})
	}
}

// request after -> handle data
instance.interceptors.response.use((response) => {
	if (response) {
		/*
			表单接口返回的都是数组
				正常返回二维数组 [[],[],[],[]]
				错误形式1 [[{Result:{
					ResponseStatus:{
						IsSuccess:false,
						MsgCode:xx,
						Errors:[{
							Message:'具体错误'
						}]
					}
				}}]]
			登录接口返回的是对象
				错误形式1 {
					IsSuccessByAPI:false,
					Message:'具体错误'
				}
		*/
		let data = response.data
		let type = getType(data)
		if (type == 'Object') {
			if (data.IsSuccessByAPI === true) {
				return data
			} else if (data.Result && data.Result.ResponseStatus) { // 保存 审核
				if (data.Result.ResponseStatus.IsSuccess) {
					if(data.Result.ResponseStatus.Errors && data.Result.ResponseStatus.Errors.length){
						// 有错误信息则提醒
						let errMsg = data.Result.ResponseStatus.Errors[0].Message
						return msg(errMsg)
					}
					return data.Result.Result || data
				} else {
					// let msg1 = data.Result.ResponseStatus.Errors[0].Message.length > 100 ? data.Result.ResponseStatus.Errors[0].Message.slice(0, 20) : data.Result.ResponseStatus.Errors[0].Message
					let msg1 = data.Result.ResponseStatus.Errors[0].Message
					return msg(msg1)
				}
			} else {
				msg(data.Message)
				return
			}
		} else if (type == 'Array') {
			if (data.length === 1 && getType(data[0]) === 'Array' && getType(data[0][0]) === 'Object' && data[0][0].Result && data[0][0].Result.ResponseStatus && data[0][0].Result.ResponseStatus.Errors) {
				let msgCode = data[0][0].Result.ResponseStatus.MsgCode
				let message = MsgCodeList[msgCode]
				message = data[0][0].Result.ResponseStatus.Errors[0].Message
				handleMsgCode(msgCode)
				return msg(message)
			}

			// 列表
			let list = []
			for (let item of data) {
				let obj = {}
				FieldKeys.forEach((it, i) => {
					obj[it] = item[i]
				})
				list.push(obj)
			}
			return list
		}
	}

}, (error) => {
	if (error && error.response) {

		// 一些接口错误需要做特定的处理：
		// ① 根据接口地址做判断 
		// 登录获取token /oauth/connect/token 接口 400 特殊处理
		// if (error.response.config.url = "/oauth/connect/token") {
		//   msg(error.response.data.error_description, "warning", 200)
		//   return null
		// }

		// ② 需要特殊处理的直接返回错误信息
		if (error.response.config.exConfig && error.response.config.exConfig.includes("customError")) {
			return error.response.data
		}

		// 错误代码的统一提示

		msg(statusMsg[error.response.status] ? statusMsg[error.response.status] : "连接错误！", "error")
		if (error.response.status == 401) {
			// 
			msg("用户凭证过期，请重新登录！（240）", "error")
			setTimeout(() => {
				uni.redirectTo({
					url: '/views/login/Login'
				})
			}, 500)
		}
		return null
	}
})

export default instance